/**
 * Copyright(c) 2014 Xunton Solutions
 *
 * History:
 *   15-10-8 下午12:23 Created by dwzhang
 */
package com.jade.bss.weixin.controller;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jade.bss.weixin.WeixinApp;
import com.jade.bss.weixin.WeixinAppConfig;
import com.jade.bss.weixin.api.component.ComponentApi;
import com.jade.bss.weixin.api.component.event.ComponentEvent;
import com.jade.bss.weixin.api.event.EventManager;
import com.jade.framework.base.context.ApplicationContextUtils;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Component控制器.
 *
 * @author <a href="mailto:dwzhang@xunton.com">dwzhang</a> 
 * @version 1.0 15-10-8 下午12:23
 */
@Controller
@RequestMapping (value = "/weixin/component")
@Api(value = "微信", hidden = true)
public class ComponentController
{
    protected Log logger = LogFactory.getLog(ComponentController.class);
    private ComponentApi componentApi = ApplicationContextUtils.getBean("bss_weixinComponentApi");
    private WeixinAppConfig appConfig;
    private EventManager eventManager = ApplicationContextUtils.getBean("bss_weixinEventManager");

    public void setAppConfig(WeixinAppConfig appConfig)
    {
        this.appConfig = appConfig;
    }

    @RequestMapping (value = "/${appCode}/autz")
    public void autz(@PathVariable (value = "appCode") String appCode,
                     @RequestParam (value = "msg_signature") String signature,
                     @RequestParam (value = "timestamp") String timestamp,
                     @RequestParam (value = "nonce") String nonce,
                     @RequestParam (value = "encrypt_type", defaultValue = "") String encryptType,
                     HttpServletRequest request,
                     HttpServletResponse response)
            throws Exception
    {
        WeixinApp app = appConfig.getApp(appCode);
        PrintWriter printWriter = response.getWriter();
        int length = request.getContentLength();
        byte[] buffer = new byte[length];
        IOUtils.readFully(request.getInputStream(), buffer);
        String message = new String(buffer, "UTF-8");

        try {
            //解密
            WXBizMsgCrypt pc = new WXBizMsgCrypt(app.getToken(), app.getDesKey(), app.getAppId());
            message = pc.decryptMsg(signature, timestamp, nonce, message);
            logger.info("receive message from open weixin platform,signature:" +
                    signature + ",timestamp:" + timestamp + ",nonce:" + nonce + ",encrypt_type:" + encryptType +
                    " from app " + app.getAppId() + ",message:" + message);
            ComponentEvent event = componentApi.parse(message);
            if (event == null) {
                logger.warn("Can't parse component event");
            }
            else {
                componentApi.handleEvent(app, event);
            }
        }
        catch (Throwable t) {
            logger.error("Can't handle component message:", t);
        }
        //返回成功
        printWriter.write("Success");
    }

    @RequestMapping (value = "/${appCode}/{appId}/callback")
    public void waiter(@PathVariable (value = "appCode") String appCode,
                       @PathVariable (value = "appId") String autzAppId,
                       @RequestParam (value = "msg_signature", required = false) String signature,
                       @RequestParam (value = "timestamp", required = false) String timestamp,
                       @RequestParam (value = "nonce", required = false) String nonce,
                       HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        WeixinApp app = appConfig.getApp(appCode);
        PrintWriter printWriter = response.getWriter();
        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String message = "", line;
        while ((line = br.readLine()) != null) {
            message += line;
        }

        //解密
        WXBizMsgCrypt pc = new WXBizMsgCrypt(app.getToken(), app.getDesKey(), app.getAppId());
        message = pc.decryptMsg(signature, timestamp, nonce, message);

        logger.info(
                "receive message from weixin message,signature:" + signature + ",timestamp:" + timestamp + ",nonce:" +
                        nonce + " body:" + message + " from app " + autzAppId);

        //todo check message
        //boolean flag = SignUtils.checkSignature(app.getToken(), timestamp, nonce, signature);
        //logger.info("####check signature from weixin:" + flag);
        //if (!flag) {
        //    throw new Exception("err.weixin.check_signature");
        //}

        //返回成功
        printWriter.write("");

        try {
            if (StringUtils.isNotEmpty(message)) {
                eventManager.handleEvent(message);
            }
        }
        catch (Exception ex) {
            logger.error("Can't handle event message:", ex);
        }
    }
}
